#define NDEBUG

#include <iostream>

#include <string.h>
#include <stdlib.h>

#include "gsupplyLinkProblem.h"
#include "gsupplyLinkTransporter.h"
#include "ogsolverBBPv3.h"
#include "ogsolverBBPv4openMP.h"
#include "ogsolverBBPv4openMP.h"
#include "glog.h"

using namespace std;

/**
 *
 */
void solveBBPv3(string str) {
    GSupplyLinkProblem slpb ;
    slpb.open(str) ;

    cout << "BBPv3 single processor" << endl ;

    // ****** BBP ******
    OGSolverBBPv3 bbp (slpb) ;
    bbp.solve() ;

    cout << "\nBestSolutionDueDateOrdered=" << (bbp.getBestSolutionDueDateOrdered()) << endl ;
    cout << "\nBestSolution=" << (bbp.getBestSolution()) << endl ;

}

/**
 *
 */
void solveBBPv4openMPrecursive(string str) {
    GSupplyLinkProblem slpb ;
    slpb.open(str) ;

    // ****** BBP ******
    OGSolverBBPv4openMPrecursive bbp (slpb) ;
    bbp.solve() ;

    cout << "\nBestSolutionDueDateOrdered=" << (bbp.getBestSolutionDueDateOrdered()) << endl ;
    cout << "\nBestSolution=" << (bbp.getBestSolution()) << endl ;

}


/**
 *
 */
void solveBBPv4openMPiterative(string str) {
    GSupplyLinkProblem slpb ;
    slpb.open(str) ;

    // ****** BBP ******
    OGSolverBBPv4openMPiterative bbp (slpb) ;
    bbp.solve() ;

    cout << "\nBestSolutionDueDateOrdered=" << (bbp.getBestSolutionDueDateOrdered()) << endl ;
    cout << "\nBestSolution=" << (bbp.getBestSolution()) << endl ;

}


/** ##########################################################################""
 *
 */
void helpCommand() {
    cout << "Usage of samebatch-multiproduct-binpacking version 1.0:" << endl ;
    cout << "samebatch-multiproduct-binpacking [options]" << endl ;
    cout << "List of options:" << endl ;
    cout << "-h                          \t prints this message" << endl ;
    cout << "-bbp <pbfilename>           \t solve a multi-product problem with bbp solver (single thread)" << endl ;
    cout << "-bbpomprecurs <pbfilename>  \t solve a multi-product problem with bbp solver (recursive multi thread)" << endl ;
    cout << "-bbpompiter <pbfilename>    \t solve a multi-product problem with bbp solver (iterative multi thread)" << endl ;

}

/**
 * Argument Line Parser
 */
void argumentLineParser(int argc, char* argv[]) {
    if (argc>1) {
        int p = 1 ;
        while (p<argc) {
            if ( !strcmp(argv[p],"-h") || !strcmp(argv[p],"-help") )
                helpCommand() ;
            // Solve BBP Problem v3
            else if ( !strcmp(argv[p],"-bbp") ) {
                if (p+1<argc)
                    solveBBPv3(argv[++p]) ;
                else
                    cout << "ERROR Problem filename missing" << endl ;
            }
            // Solve BBP Problem OpenMP recursive
            else if ( !strcmp(argv[p],"-bbpomprecurs") || !strcmp(argv[p],"-bbpopenmprecurs") ) {
                if (p+1<argc)
                    solveBBPv4openMPrecursive(argv[++p]) ;
                else
                    cout << "ERROR Problem filename missing" << endl ;
            }
            // Solve BBP Problem OpenMP iterative
            else if ( !strcmp(argv[p],"-bbpompiter") || !strcmp(argv[p],"-bbpopenmpiter") ) {
                if (p+1<argc)
                    solveBBPv4openMPiterative(argv[++p]) ;
                else
                    cout << "ERROR Problem filename missing" << endl ;
            }
            else {
                cout << "Argument line error : args[" << p << "]=" << argv[p] << endl ;
            }
            p++ ;
        }
    }
    else
        helpCommand() ;
}


/**
 *
 */
int main(int argc, char* argv[])
{
    argumentLineParser(argc, argv) ;
    //cout << "Samebatch, multiproduct, binpacking, supplylink solver" << endl;
    //solveSameBatchFileCommand("data/glsdsp-samebatch-sl1np10t1.txt") ;
    //solveSameBatchFileCommand("data/glsdsp-samebatch-sl1np60t1-instance02.txt") ;
    //solveSameBatchFileCommand("data/instance050c1.txt") ;

    return 0;
}


